home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Languages / Masm V6.11 / SAMPLES / DEMOS / MATHDEMO.C$ / MATHDEMO.bin
Encoding:
Text File  |  1993-09-03  |  14.3 KB  |  389 lines

  1. /* MATHDEMO.C - Creates a simple on-screen calculator with functions for
  2.  * basic integer arithmetic and for solving for the roots of a quadratic
  3.  * equation. MATHDEMO invokes procedures that illustrate assembly-language
  4.  * instructions related to mathematics, including those specific to the
  5.  * 8087 family of coprocessors.
  6.  *
  7.  * MATHDEMO.EXE is built from the following files:
  8.  *    MATHDEMO.C - Main program
  9.  *    MATH.ASM   - Assembly procedures for MATHDEMO
  10.  *    COMMON.ASM - Assembly procedures shared by other example programs
  11.  *    DEMO.INC   - Assembly include file with macros and structure declarations
  12.  *    DEMO.H     - C include file with prototypes and structure declarations
  13.  *
  14.  * Procedures:  AddLong       MulLong      DivLong     Quadratic
  15.  *              SubLong       ImulLong     IdivLong
  16.  */
  17.  
  18. #include "demo.h"
  19. #include <dos.h>
  20. #include <conio.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23.  
  24. /* Function prototypes */
  25. void display_calc( void );
  26. void display_help( void );
  27. void press( void );
  28. void push( int sign );
  29.  
  30. /* Global variables */
  31. long s1, s2, s3;                /* Stack values: 1st, 2nd, 3rd      */
  32. char entry[11];                 /* Entry window string              */
  33. int  col;                       /* Current display column for entry */
  34.  
  35. main()
  36. {
  37.     int ch, err;                        /* Keyboard character, return val  */
  38.     static int sign, mode;              /* Sign flag, signed/unsigned flag */
  39.     static float root1, root2;          /* Roots of quadratic equation     */
  40.     static short quotient, remainder;   /* Results of division             */
  41.     static long *product, result;
  42.     static char *rmsg[2] = { "Complex", "roots" };
  43.     static char *dmsg[2] = { "Division by", "Zero" };
  44.     static char *highmsg = { "high:" };
  45.     static char *lowmsg  = { "low:" };
  46.  
  47.     GetVidConfig();
  48.     display_calc();
  49.     StrWrite( 9, 14, "+" );
  50.     col = 20;
  51.     do
  52.     {
  53.         SetCurPos( 9, col );
  54.         if (( ch = getch()) == 0 )
  55.       getch(); 
  56.     else 
  57.           switch( (ch = toupper( ch )) )
  58.           {
  59.             /* Display number in entry window. */
  60.             case '0':
  61.             case '1':
  62.             case '2':
  63.             case '3':
  64.             case '4':
  65.             case '5':
  66.             case '6':
  67.             case '7':
  68.             case '8':
  69.             case '9':
  70.                 putch( (char) ch );
  71.                 entry[col - 20] = (char) ch;
  72.                 entry[++col - 20] = 0;
  73.                 if( col == 30 )
  74.                     col--;
  75.                 break;
  76.  
  77.             /* Toggle between signed and unsigned arithmetic modes. */
  78.             case 'M':
  79.                 if( mode )
  80.                 {
  81.                     mode = 0;                   /* For signed mode,   */
  82.                     StrWrite( 14, 57, "  (" );  /*   toggle flag off  */
  83.                     StrWrite( 9, 14, "+" );     /*   and restore sign */
  84.                 }
  85.                 else
  86.                 {
  87.                     mode++;                     /* For unsigned mode, */
  88.                     StrWrite( 14, 57, "(un" );  /*   toggle flag on   */
  89.                     StrWrite(  9, 14, " " );    /*   and blank sign   */
  90.                 }
  91.                 sign = 0;
  92.                 break;
  93.  
  94.             /* Solve for x in quadratic equation s3*x*x + s2*x + s3 = 0. */
  95.             case 'Q':
  96.                 push( sign );
  97.                 err = Quadratic( (float)s3, (float)s2, (float)s1,
  98.                                   &root1, &root2 );
  99.                 ClearBox( 7, 9, 15, 9, 29 );    /* Clear entry window   */
  100.                 ClearBox( 7, 9, 49, 10, 66 );   /* Clear result window  */
  101.                 if( err < 2 )
  102.                 {
  103.                     SetCurPos( 9, 50 );
  104.                     printf( "%16.3f", root1 );          /* Display 1st root */
  105.                     if( !err )
  106.                     {
  107.                         SetCurPos( 10, 50 );
  108.                         printf( "%16.3f", root2 );      /* Display 2nd root */
  109.                     }
  110.                 }
  111.                 if( err == 2)
  112.                 {
  113.                     StrWrite(  9, 50, rmsg[0] );   /* Display "Complex  */
  114.                     StrWrite( 10, 50, rmsg[1] );   /*   roots"          */
  115.                 }
  116.                 break;
  117.  
  118.             /* Change sign. */
  119.             case 'S':
  120.                 if( !mode )             /* Allow sign changes only */
  121.                 {                       /*   in signed mode        */
  122.                     if( sign )
  123.                     {
  124.                         StrWrite( 9, 14, "+" );
  125.                         sign = 0;
  126.                     }
  127.                     else
  128.                     {
  129.                         StrWrite( 9, 14, "-" );
  130.                         sign++;
  131.                     }
  132.                 }
  133.                 break;
  134.  
  135.             /* Clear stack, reinitialize variables. */
  136.             case 'C':
  137.                 s3 = s2 = s1 = 0;
  138.                 ClearBox( 7, 9, 15, 9, 29 );    /* Clear entry window  */
  139.                 ClearBox( 7, 9, 49, 10, 66 );   /* Clear result window */
  140.                 entry[0] = 0;
  141.                 col = 20;
  142.                 break;
  143.  
  144.             /* Push values down stack when ENTER key pressed. */
  145.             case CR:
  146.                 push( sign );
  147.                 break;
  148.  
  149.             /* Display help screen. */
  150.             case '?':
  151.             case 'H':
  152.                 display_help();                 /* Display help         */
  153.                 display_calc();                 /* Redisplay calculator */
  154.                 StrWrite( 9, 20, entry );       /*   and entry number   */
  155.                 if( mode )
  156.                 {
  157.                     StrWrite( 14, 57, "(un" );  /* Make "unsigned"      */
  158.                     StrWrite(  9, 14, " " );    /*   and blank sign     */
  159.                 }
  160.                 else
  161.                 {
  162.                     if( sign )
  163.                         StrWrite( 9, 14, "-" );
  164.                     else
  165.                         StrWrite( 9, 14, "+" );
  166.                 }
  167.                 break;
  168.  
  169.             /* Add or subtract s1 and s2. */
  170.             case '+':
  171.             case '-':
  172.                 push( sign );
  173.                 if( (char) ch == '+' )
  174.                     s1 = AddLong( s2, s1 );
  175.                 else
  176.                     s1 = SubLong( s2, s1 );
  177.                 ClearBox( 7, 9, 15, 9, 29 );    /* Clear entry window   */
  178.                 ClearBox( 7, 9, 49, 10, 66 );   /* Clear result window  */
  179.                 SetCurPos( 9, 56 );
  180.                 if( mode )
  181.                     printf( "%lu", s1 );        /* Display unsigned or  */
  182.                 else
  183.                     printf( "%li", s1 );        /*   signed result      */
  184.                 break;
  185.  
  186.             /* Multiply s1 and s2. */
  187.             case '*':
  188.                 push( sign );
  189.                 if( mode )
  190.                     product = MulLong(  s2, s1 );
  191.                 else
  192.                     s1      = ImulLong( s2, s1 );
  193.                 ClearBox( 7, 9, 15, 9, 29 );    /* Clear entry window   */
  194.                 ClearBox( 7, 9, 49, 10, 66 );   /* Clear result window  */
  195.                 if( mode )
  196.                 {
  197.                     StrWrite(  9, 50, highmsg );
  198.                     StrWrite( 10, 50, lowmsg );
  199.                     SetCurPos( 9, 56 );
  200.                     printf( "%lu", *++product ); /* Display high and low   */
  201.                     SetCurPos( 10, 56 );         /*   double-word of       */
  202.                     printf( "%lu", *--product ); /*   unsigned product     */
  203.                     s1 = *product;               /* Copy low word to stack */
  204.                 }
  205.                 else
  206.                 {
  207.                     SetCurPos( 9, 56 );
  208.                     printf( "%li", s1 );        /* Display signed product  */
  209.                 }
  210.                 break;
  211.  
  212.             /* Divide s2 by s1. */
  213.             case '/':
  214.                 push( sign );
  215.                 if ( s1 == 0 )
  216.                 {
  217.                     StrWrite(  9, 50, dmsg[0] );   /* Display "Division by */
  218.                     StrWrite( 10, 50, dmsg[1] );   /*   zero"              */
  219.                 }
  220.                 else
  221.                 {
  222.                     if( mode )
  223.                         quotient = DivLong(  s2, (int) s1, &remainder );
  224.                     else
  225.                         quotient = IdivLong( s2, (int) s1, &remainder );
  226.                     ClearBox( 7, 9, 15, 9, 29 );   /* Clear entry          */
  227.                     ClearBox( 7, 9, 49, 10, 66 );  /* Clear result         */
  228.                     if( abs( (int) remainder ) >= (abs( (int) s1 ) >> 1) )
  229.                     {
  230.                         if( quotient >= 0 )        /* Round up if          */
  231.                             quotient++;            /*   remainder > s1/2   */
  232.                         else
  233.                             quotient--;
  234.                     }
  235.                     SetCurPos( 9, 56 );
  236.                     if( mode )
  237.                         printf( "%u", quotient );   /* Display result */
  238.                     else
  239.                         printf( "%i", quotient );
  240.                     s1 = (long) quotient;           /* Copy quotient to stack */
  241.                 }
  242.                 break;
  243.  
  244.           } //  Switch
  245.     } while( ch != ESCAPE );
  246.  
  247.     clear_scrn( 7, 0, 24 );             /* Clear screen before exit   */
  248.     SetCurPos( 23, 0 );                 /*   and set cursor to bottom */
  249.     return( 0 );
  250. }
  251.  
  252.  
  253. /* display_calc - Clears screen and displays calculator.
  254.  *
  255.  * Params:  None
  256.  */
  257.  
  258. void display_calc( void )
  259. {
  260.     static char *calculator[19] =
  261.     {
  262.    "                  ***   MATH Demonstration Program  ***",
  263.    "",
  264.    "",
  265.    "┌─ Integer Calculator ───────────────────────────────────────────────────┐",
  266.    "│                                                                        │",
  267.    "│         ┌────────────────┐                 ┌──────────────────┐        │",
  268.    "│         │                │                 │                  │        │",
  269.    "│         └────────────────┘                 │                  │        │",
  270.    "│                      entry                 └──────────────────┘        │",
  271.    "│                                                          result        │",
  272.    "│         7  8  9      +   -                 ? = Help                    │",
  273.    "│                                            M = Mode   (signed)         │",
  274.    "│         4  5  6      *   /                 S = Change sign             │",
  275.    "│                                            Q = Solve quadratic         │",
  276.    "│         1  2  3      ─┘ Enter             C = Clear all               │",
  277.    "│                                                                        │",
  278.    "│            0                             Esc = Quit                    │",
  279.    "│                                                                        │",
  280.    "└────────────────────────────────────────────────────────────────────────┘"
  281.     };
  282.     int i;
  283.  
  284.     clear_scrn( 7, 0, 24 );
  285.     if( vconfig.display )
  286.         ClearBox( 31, 6, 2, 21, 77 );
  287.     else
  288.         ClearBox( 15, 6, 2, 21, 77 );
  289.     ClearBox( 7, 9, 14, 9, 29 );                /* Clear entry window  */
  290.     ClearBox( 7, 9, 49, 10, 66 );               /* Clear result window */
  291.     for( i = 0; i < 19; i++)                    /* Display calculator  */
  292.         StrWrite( i + 3, 3, calculator[i] );
  293. }
  294.  
  295.  
  296.  
  297. /* display_help - Clears screen and displays help text.
  298.  *
  299.  * Params:  None
  300.  */
  301.  
  302. void display_help( void )
  303. {
  304.     static char *help_msg[24] =
  305.     {
  306.         "The Integer Calculator works somewhat like an RPN hand "
  307.         "calculator.  Type the", "first integer, press Enter (─┘), type the "
  308.         "second integer, and press the", "desired operator key.  The answer "
  309.         "appears in the result window.",
  310.         "",
  311.         "To keep things simple, the Integer Calculator handles only long or "
  312.         "short", "integers -- no floating point numbers allowed.  Unsigned "
  313.         "numbers can range", "from 0 to 4,294,967,295; signed numbers from "
  314.         "-2,147,483,648 to 2,147,483,647.", "There's one exception to "
  315.         "this:  when dividing two numbers, the divisor must", "be a short "
  316.         "integer from 0 to 65,535 for unsigned division, or from -32,768",
  317.         "to 32,767 for signed division.",
  318.         "",
  319.         "Press the M key to toggle between signed and unsigned arithmetic.  " \
  320.         "Press the", "S key to change the sign of the number in the entry "
  321.         "window.  You'll notice", "the Calculator allows a change of sign "
  322.         "only in \"signed\" mode.",
  323.         "",
  324.         "The Calculator uses coprocessor instructions (either real or "
  325.         "simulated) to", "solve for the roots of a quadratic equation in "
  326.         "the form",
  327.         "",
  328.         "                     A*x*x + B*x + C = 0",
  329.         "",
  330.         "Enter the three equation constants A, B, and C in order, then "
  331.         "press Q.  The", "roots, if they exist, appear in the result "
  332.         "window.  If the equation has only", "one root, then only a single "
  333.         "number is displayed.  For example, try entering", "3, 7, and 2 "
  334.         "for A, B, and C."
  335.     };
  336.     int i;
  337.  
  338.     clear_scrn( 7, 0, 24 );
  339.     for( i = 0; i < 24; i++)
  340.         StrWrite( i, 0, help_msg[i] );
  341.     press();
  342. }
  343.  
  344.  
  345. /* push - Pushes values down one stack position:  s3 becomes s2,
  346.  * s2 becomes s1, and s1 becomes the value in the entry window.
  347.  *
  348.  * Params:  sign - Current sign status (0 = positive, 1 = negative)
  349.  */
  350.  
  351. void push( int sign )
  352. {
  353.     unsigned long place;
  354.  
  355.     s3    = s2;
  356.     s2    = s1;
  357.     s1    = 0;
  358.     place = 1;
  359.     if( entry[col - 20] )
  360.     {
  361.         s1    = (long) (entry[col - 20] - '0');
  362.         place = 10;
  363.     }
  364.     while( col > 20 )
  365.     {
  366.         s1    += place * (long) (entry[--col - 20] - '0');
  367.         place *= 10;
  368.     }
  369.     if( sign )
  370.         s1 = -s1;
  371.     ClearBox( 7, 9, 15, 9, 29 );        /* Clear entry window        */
  372.     entry[0] = 0;                       /* Reinitialize entry string */
  373.     col      = 20;                      /* Reset column count        */
  374. }
  375.  
  376.  
  377. /* press - Prompt for keyboard signal to continue.
  378.  *
  379.  * Params:  None
  380.  */
  381.  
  382. void press( void )
  383. {
  384.     SetCurPos( 24, 49 );
  385.     printf( ". . . press a key to continue" );
  386.     SetCurPos( 24, 47 );
  387.     getch();
  388. }
  389.